package cardsdk

import (
	"errors"

	"gitee.com/fhe-search/fhe-search-rpc/g"

	"strings"

	"gitee.com/fhe-search/nfhedecd/denseComputiing"
	"gitee.com/fhe-search/nfhedecd/interfaceAPI"
)

func SM1ShortUtf8Enc(utf8ClearText string) ([]byte, error) {
	const utf8ByteLen = 1000
	if len(utf8ClearText) > utf8ByteLen {
		return nil, errors.New("UTF8 length too long")
	}
	return denseComputiing.PEncStr(utf8ClearText, 1)
}

func SM1ShortUtf8Dec(utf8EncText []byte) (string, error) {
	if len(utf8EncText) == 0 {
		return "", errors.New("nil UTF8 enc text")
	}
	secretKeyPath := g.GetConfig().FheSearchConfig.SecretKeyPath
	UserAuthPassword1 := interfaceAPI.ExportUserAuthPWPrefix(1, secretKeyPath)
	utf8DecText, err := denseComputiing.PDecStr(utf8EncText, 1, UserAuthPassword1)
	if err != nil {
		return "", err
	}
	utf8DecText = strings.TrimRight(utf8DecText, "\000") // 去除多余的字节
	return utf8DecText, nil
}

func SM1LongUtf8Enc(utf8ClearText string) ([]byte, error) {
	utf8EncTextBytes := []byte{}
	for i := 0; i < len(utf8ClearText)/1000; i++ {
		s1 := utf8ClearText[i*1000 : (i+1)*1000]
		utf8EncText, err := SM1ShortUtf8Enc(s1)
		if err != nil {
			return nil, err
		}
		utf8EncTextBytes = append(utf8EncTextBytes, utf8EncText...)
	}
	if len(utf8ClearText)%1000 != 0 {
		s1 := []byte(utf8ClearText[(len(utf8ClearText)/1000)*1000:])
		//补0
		//for i := 0; i < 1000-(len(utf8ClearText)%1000); i++ {
		//	s1 = append(s1, 0)
		//}
		utf8EncText, err := SM1ShortUtf8Enc(string(s1))
		if err != nil {
			return nil, err
		}
		utf8EncTextBytes = append(utf8EncTextBytes, utf8EncText...)
	}
	return utf8EncTextBytes, nil
}

func SM1LongUtf8Dec(utf8EncText []byte) (string, error) {
	//if len(utf8EncText)%1012 != 0 {
	//	return "", fmt.Errorf("EncText length can not be a multiple of 128")
	//}
	const utf8DecByteLen = 1012
	utf8DecTextBytes := []byte{}
	for i := 0; i < len(utf8EncText)/utf8DecByteLen; i++ {
		uint16EncText := utf8EncText[i*utf8DecByteLen : (i+1)*utf8DecByteLen]
		uint16ClearText, err := SM1ShortUtf8Dec(uint16EncText)
		if err != nil {
			return "", err
		}
		utf8DecTextBytes = append(utf8DecTextBytes, uint16ClearText...)
	}

	if len(utf8EncText)%utf8DecByteLen != 0 {
		b1 := utf8EncText[(len(utf8EncText)/utf8DecByteLen)*utf8DecByteLen:]
		uint16ClearText, err := SM1ShortUtf8Dec(b1)
		if err != nil {
			return "", err
		}
		utf8DecTextBytes = append(utf8DecTextBytes, uint16ClearText...)
	}

	return string(utf8DecTextBytes), nil
}

const UiKeyIndex = 1

// PEncS32ExWrapper
/*
这个接口有问题 -- 已修复
比如对[]int{1,2,3,4,5,6,7,8,9}
加密出来的密文，解密之后获得[]int{1,0,2,0,3,0,4,0,5}
暂时先使用接口PEncS32ExWrapper2代替
*/
func PEncS32ExWrapper(int32Arr []int32) ([][]byte, error) {
	var uiKeyIndexs []uint
	for i := 0; i < len(int32Arr); i++ {
		uiKeyIndexs = append(uiKeyIndexs, UiKeyIndex)
	}
	encData, err := denseComputiing.PEncS32Ex(uiKeyIndexs, uint(len(int32Arr)), int32Arr)
	if err != nil {
		return nil, err
	}
	var res [][]byte
	//fmt.Println(hex.EncodeToString(encData))
	const UnitEncLen = 16
	for i := 0; i < len(encData)/UnitEncLen; i++ {
		res = append(res, encData[i*UnitEncLen:(i+1)*UnitEncLen])
		//fmt.Println(hex.EncodeToString(res[i]))
	}
	return res, nil
}

func PEncS32ExWrapper2(int32Arr []int) ([][]byte, error) {
	res := make([][]byte, len(int32Arr))
	for i := 0; i < len(int32Arr); i++ {
		encData, err := PEncS32Wrapper(int32(int32Arr[i]))
		if err != nil {
			return nil, err
		}
		res[i] = encData
	}
	return res, nil
}

func PDecS32Wrapper(encData []byte) (int32, error) {
	secretKeyPath := g.GetConfig().FheSearchConfig.SecretKeyPath
	UserAuthPassword := interfaceAPI.ExportUserAuthPWPrefix(UiKeyIndex, secretKeyPath)
	plainData, err := denseComputiing.PDecS32(encData, UiKeyIndex, UserAuthPassword)
	if err != nil {
		return 0, err
	}
	return plainData, nil
}

func PEncS32Wrapper(plain int32) ([]byte, error) {
	encData, err := denseComputiing.PEncS32(UiKeyIndex, plain)
	//fmt.Println(hex.EncodeToString(encData))
	return encData, err
}
